<?php

/*
	This file is part of Mandragon.

    Mandragon is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Mandragon is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Mandragon.  If not, see <http://www.gnu.org/licenses/>.
*/

include_once('sys/regionfunctions.inc');
include_once("sys/interfaces.inc");

class GroupyPage {

	private $alerter;
	
	public function __construct() {
		$this->alerter = new Alerter();
	}

	/**
	 * adds extra access checks, dependent on page state
	 */
	function page_inc_check_access($page) {
		check_access("READ");
	}

	function page_inc_execute_action($action) {
		$action = GroupAction::getAction($action);
		$action->execute();
	}

	/**
	 * execute page logic
	 */
	function page_inc_execute($page) {
		$manager = new GameManager();
		
		if (!$_GET['action']) {
		
			$sqlresult = db_do_query($page, db_query_select(array(array(), "GROUPY.*, MEMBER.nick AS admin_nick"), array("GROUPY INNER JOIN MEMBER ON GROUPY.admin = MEMBER.user_id"), "groupy_id = {$page->id}"));
			if (db_num_rows($sqlresult) != 1)
				errorpage(404);
			$groupy = db_fetch_array($sqlresult);
			
			if ($groupy['admin'] == $_SESSION['user_id'])
				add_action("groupy-edit", "url-action", "edit");
			
			// fetch regional info
			if ($groupy['region_id']) {
				$region_tree = region_get_regions();
				$groupy['region'] = region_get_region_tree($groupy['region_id'], $region_tree);
			}
			
			// fetch member info
			$groupy['members'] = array();
			$sqlresult = db_do_query($page, db_query_select(array(array(), "MEMBER.nick, MEMBER.user_id"), array("IN_GROUP INNER JOIN MEMBER ON IN_GROUP.user_id = MEMBER.user_id", "DUMMY"), "groupy_id = {$page->id}", "nick ASC"));
			if (db_num_rows($sqlresult) > 0)
				while ($m = db_fetch_array($sqlresult))
					$groupy['members'][] = $m;
			
			// fetch gaming info
			$groupy['games'] = array();
			$sqlresult = db_do_query($page, db_query_select(array(array(), "PLAY_STATUS.*, GROUPY_PLAYS.game_id"), array("GROUPY_PLAYS INNER JOIN PLAY_STATUS ON GROUPY_PLAYS.play_status_id = PLAY_STATUS.play_status_id", "DUMMY"), "groupy_id = {$page->id}"));
			if (db_num_rows($sqlresult) > 0) {
				$game_tree = $manager->game_get_games();
				while ($g = db_fetch_array($sqlresult))
					$groupy['games'][] = array('game' => $game_tree[$g['game_id']], 'play_status' => $g['play_status']);
			}
			
			$page->content['groupy'] = $groupy;
		}
		
		$page->content['title'] = "Spelersgroep: " . (($_GET['action'] == "add") ? "toevoegen" : (($_GET['action'] == "edit") ? "aanpassen" : "'{$groupy['groupname']}'"));
	}


	/**
	 * dress up page content using skin stuff
	 */
	function page_inc_dress($page) {
		print_body($page);
		if (($_GET['action'] == "edit") or ($_GET['action'] == "add"))
			print_form($page, $page->content['form']);
		else
			print_groupy($page->content['groupy']);
	}
}

class GroupEditAction extends GroupAction implements iAction {

	public function execute($page) {
		if (!$page->id)
			errorpage(9);
		$sqlresult = db_do_query($page, db_query_select(array(array("*")), array("GROUPY"), "groupy_id = {$page->id}"));
		if (db_num_rows($sqlresult) != 1)
			errorpage(404);
		$groupy = db_fetch_array($sqlresult);
		if ($groupy['admin'] != $_SESSION['user_id'])
			errorpage(5);
	}
}

class GroupAddAction extends GroupAction implements iAction {
	private $checker;
	private $creator;
	private $manager;
	
	public function __construct() {
		$this->checker = new InputChecker();			
		$this->creator = new FormCreator();
		$this->manager = new GameManager();
	}

	public function execute($page) {
		global $CONFIG;
		if (!$_SESSION['user_id'])
			errorpage(6);
			
		if ($_POST['submitted'] && $this->validate_group()) {
			$groupy_id = $this->get_groupy_id($this->get_admin_id());
			$this->process_regions($groupy_id);
			$this->process_members($groupy_id);
			$this->process_games($groupy_id);
			
			endpage("OK, de gegevens zijn verwerkt!<script language=JavaScript>setTimeout(\"location.href='/service/{$groupy_id}.groupy'\", 1500);</script>"); //TODO: extract javascript
		} else {
			$this->create_group_form($inputs);
		}
	}

	private function get_admin_id() {
		$sqlresult = db_do_query($page, db_query_select(array(array('user_id')), array('MEMBER'), "nick LIKE '{$_POST["admin"]}'"));
		$m = db_fetch_array($sqlresult);
		return $m['user_id'];
	}

	private function create_group_form($page) {
		$inputs = array();
		$inputs = array_merge($inputs, $this->create_form_header());
		$inputs = array_merge($inputs, $this->create_form_regions_section());
		
		$inputs[] = $this->creator->input_text("Beschrijving", "description", $groupy['description']);

		$inputs = array_merge($inputs, $this->create_form_player_section());
		$inputs = array_merge($inputs, $this->create_form_game_section());

		$page->content['form'] = $this->creator->create('groupform', array_reverse($inputs));
	}

	private function create_form_game_section() {
		$inputs = array();
		$inputs[] = $this->creator->header("Spellen");
	
		$play_status = get_keys_and_values("play_status_id", "play_status", "PLAY_STATUS");
		$game_tree = $this->manager->game_get_games();
		$game_types = get_keys_and_values("game_type_id", "game_type", "GAME_TYPE");
		$game_kv = $this->manager->game_get_games_kv();
		
		$games = db_do_query($page, db_query_select(array(array("game_id, play_status_id")), array("GROUPY_PLAYS"), "groupy_id = " . intval($groupy['groupy_id'])));
		
		$n = 0;
		if (db_num_rows($games) > 0) {
			while ($g = db_fetch_array($games)) {
				$n++;
				$inputs[] = $this->creator->input_hidden("game_{$n}", $g['game_id']);
				$inputs[] = $this->creator->input_select("Spel #{$n}", "game_{$n}_dummy", $game_kv['keys'], $game_kv['values'], "", $g['game_id'], "", 1, 1);
				$inputs[] = $this->creator->input_select("", "game_{$n}_freq", $play_status['keys'], $play_status['values'], "", $g['play_status_id']);
				$inputs[] = $this->creator->input_checkbox("Verwijder dit spel", "game_{$n}_del");
			}	
		}
		$inputs[] = $this->creator->input_hidden("registered_games", $n);
		$inputs[] = $this->creator->input_select("Spellen toevoegen", "new_games", array("NONE", 1, 2, 3, 4, 5), array("geen", "1 spel", "2 spellen", "3 spellen", "4 spellen", "5 spellen"), "", "", "document.groupform.submit()");
		
		if ($_POST['new_games'] != "NONE") {
			$max = $n + $_POST['new_games'];
			array_unshift($game_kv['keys'], "NEW");
			array_unshift($game_kv['values'], "nieuw spel toevoegen");
			for ($n = $n+1; $n <= $max; $n++) {
				$inputs[] = $this->creator->input_select("Spel #{$n}", "game_{$n}", $game_kv['keys'], $game_kv['values'], "kies een spel", "", "document.groupform.submit()");
				if ($_POST["game_{$n}"] == "NEW") {
					$inputs[] = $this->creator->input_select("Spel #{$n} - soort", "game_{$n}_type", $game_types['keys'], $game_types['values']);
					$inputs[] = $this->creator->input_field("Spel #{$n} - naam", "game_{$n}_name");
				}
					
				$inputs[] = $this->creator->input_select("", "game_{$n}_freq", $play_status['keys'], $play_status['values']);
			}	
		}
		return $inputs;
	}

	private function create_form_player_section() {
		$inputs = array();
		$inputs[] = $this->creator->header("Leden");
		
		$members = db_do_query($page, db_query_select(array(array(), "MEMBER.nick, MEMBER.user_id"), array("MEMBER INNER JOIN IN_GROUP ON MEMBER.user_id = IN_GROUP.user_id", "DUMMY"), "groupy_id = " . intval($groupy['groupy_id'])));
		$n = 0;
		if (db_num_rows($members) > 0) {
			while ($m = db_fetch_array($members)) {
				$n++;
				$inputs[] = $this->creator->input_hidden("member_{$n}", $m['user_id']);
				$inputs[] = $this->creator->input_checkbox("Verwijder {$m['nick']} uit de groep", "member_{$n}_kick");
			}
		}
		$inputs[] = $this->creator->input_hidden("registered_members", $n);
		$inputs[] = $this->creator->input_select("Leden toevoegen", "new_members", array("NONE", 1, 2, 3, 4, 5, 6, 7, 8), array("geen", "1 lid", "2 leden", "3 leden", "4 leden", "5 leden", "6 leden", "7 leden", "8 leden"), "", "", "document.groupform.submit()");
		
		if ($_POST['new_members']) {
			$max = $_POST['new_members'] + $n;
			for ($n = $n+1; $n <= $max; $n++) {
				$inputs[] = $this->creator->input_field("Lid #$n", "member_{$n}");
			}
		}			
		return $inputs;
	}

	private function create_form_regions_section() {
		$inputs = array();
		if (($_POST['region'] == "NEW")) {
			$kv = region_get_regions_kv(1);
			$inputs[] = $this->creator->input_field("Regio", "region_name");
			$inputs[] = $this->creator->input_select("Locatie", "region", $kv['keys'], $kv['values'], "kies een regio", $profile['region_id']);
		} else {
			$kv = region_get_regions_kv();
			$inputs[] = $this->creator->input_select("Regio", "region", array_merge(array("NEW"), $kv['keys']), array_merge(array("NIEUWE REGIO"), $kv['values']), "kies een regio", $groupy['region_id'], "document.groupform.submit()");
		}
		return $inputs;
	}

	private function create_form_header() {
		$inputs = array();
		$inputs[] = $this->creator->header("Groepsgegevens");
		$inputs[] = $this->creator->input_field("Naam", "groupname", $groupy['groupname']);
		$inputs[] = $this->creator->input_field("Beheerder", "admin", $_SESSION['member']['nick']);
		return $inputs;
	}

	private function process_regions($groupy_id) {
		if ($_POST['region'] != intval($groupy['region_id'])) {
			if (ereg("^parent[0-9]+$", $_POST['region'])) { // new region
				db_do_query($page, db_query_insert(array('name'), array(db_sqlize($_POST['region_name'])), "REGION"));
				$region_id = db_insert_id();
				db_do_query($page, db_query_insert(array('parent_region', 'sub_region'), array(substr($_POST['region'], 6), $region_id), "REGION_TREE"));
			} else {
				$region_id = $_POST['region'];
			}
			db_do_query($page, db_query_update(array('region_id'), array($region_id), "GROUPY", "groupy_id = {$groupy_id}"));
		}
	}

	private function get_groupy_id($admin_id) {
		if ($_GET['action'] == "add") { // add group
			db_do_query($page, db_query_insert(array('admin', 'description', 'groupname'), array($admin_id, db_sqlize($_POST['description']), db_sqlize($_POST['groupname'])), "GROUPY"));
			return db_insert_id();
		} else { // update group
			db_do_query($page, db_query_update(array('admin', 'description', 'groupname'), array($admin_id, db_sqlize($_POST['description']), db_sqlize($_POST['groupname'])), "GROUPY", "groupy_id = {$groupy['groupy_id']}"));
			return $groupy['groupy_id'];
		}
	}

	private function process_members($groupy_id) {
		$registered = intval($_POST['registered_members']);
		$new = ($_POST['new_members'] != "NONE") ? intval($_POST['new_members']) : 0;
		$member_ids = $this->get_members($registered, $new);	
		for ($i = 1; $i <= $registered; $i++)
			if ($_POST["member_{$i}_kick"]) {
				db_do_query($page, db_query_delete("IN_GROUP", "user_id = {$member_ids[$i]} AND groupy_id = {$groupy_id}"));
				$this->alerter->add_alert("{$_SESSION['member']['nick']} heeft je uit spelersgroep <a href=/service/{$groupy_id}.groupy>{$_POST['groupname']}</a> verwijderd", "", $member_ids[$i]);
			}
		for ($i = $registered+1; $i <= $registered + $new; $i++) {
			db_do_query($page, db_query_insert(array('user_id', 'groupy_id'), array($member_ids[$i], $groupy_id), "IN_GROUP"));
			$this->alerter->add_alert("{$_SESSION['member']['nick']} heeft je aan spelersgroep <a href=/service/{$groupy_id}.groupy>{$_POST['groupname']}</a> toegevoegd", "", $member_ids[$i]);
		}
	}

	private function get_members($registered, $new) {
		$member_ids = array();
		
		for ($i = 1; $i <= $registered; $i++) {
			$member_ids[$i] = $_POST["member_$i"];
		}
		for ($i = $registered + 1; $i <= $registered + $new; $i++) {
			if ($this->checker->check_chars($_POST["member_{$i}"], "lid #$i heeft een ongeldige gebruikersnaam")) {
				$sqlresult = db_do_query($page, db_query_select(array(array('user_id')), array('MEMBER'), "nick LIKE '{$_POST["member_{$i}"]}'"));
				$m = db_fetch_array($sqlresult);
				$member_ids[$i] = $m['user_id'];
			}
		}
		return $member_ids;
	}
	
	private function process_games($groupy_id) {
		$registered = intval($_POST['registered_games']);
		$new = ($_POST['new_games'] != "NONE") ? intval($_POST['new_games']) : 0;
		for ($i = 1; $i <= $registered; $i++) {
			if ($_POST["game_{$i}_del"])
				db_do_query($page, db_query_delete("GROUPY_PLAYS", "groupy_id = {$groupy_id} AND game_id = {$_POST["game_{$i}"]}"));
			else 
				db_do_query($page, db_query_update(array('play_status_id'), array($_POST["game_{$i}_freq"]), "GROUPY_PLAYS", "groupy_id = {$groupy_id} AND game_id = {$_POST["game_{$i}"]}"));
		}
		for ($i = $registered+1; $i <= $registered + $new; $i++) {
			if ($_POST["game_{$i}"] == "NEW") {
				db_do_query($page, db_query_insert(array('name'), array(db_sqlize($_POST["game_{$i}_name"])), "GAME"));
				$game_id = db_insert_id();
				db_do_query($page, db_query_insert(array('game_id', 'game_type_id'), array($game_id, $_POST["game_{$i}_type"]), "GAME_OF_TYPE"));
			} else
				$game_id = $_POST["game_{$i}"];
			db_do_query($page, db_query_insert(array('groupy_id', 'game_id', 'play_status_id'), array($groupy_id, $game_id, $_POST["game_{$i}_freq"]), "GROUPY_PLAYS"));
		}
	}

	private function validate_group() {
		$ok = $this->checker->check_exists($_POST['groupname'], "naam");
		$ok = $ok && $this->checker->check_tags($_POST['groupname'], "naam");
		if (ereg("^parent[0-9]+$", $_POST['region'])) {
			$ok = $ok && $this->checker->check_exists($_POST['region_name'], "naam regio");
			$ok = $ok && $this->checker->check_tags($_POST['region_name'], "naam regio");
		}
		if ($this->checker->check_chars($_POST["admin"], "beheerder heeft een ongeldige gebruikersnaam")) {
			$sqlresult = db_do_query($page, db_query_select(array(array('user_id')), array('MEMBER'), "nick LIKE '{$_POST["admin"]}'"));
			$ok = $ok && $this->checker->check_input(db_num_rows($sqlresult) == 1, "lid '{$_POST["admin"]}' is onbekend");
			$m = db_fetch_array($sqlresult);
			$adminid = $m['user_id'];
		}

		$ok = $ok && $this->checker->check_exists($_POST['description'], "beschrijving");
		$ok = $ok && $this->checker->check_tags_advanced($_POST['description'], "beschrijving"); 
		$ok = $ok && $this->checker->check_tag_closures($_POST['description'], "beschrijving");
		$ok = $ok && $this->checker->check_exists($_POST['region'], "locatie");
		
		$registered = intval($_POST['registered_members']);
		$new = ($_POST['new_members'] != "NONE") ? intval($_POST['new_members']) : 0;
		
		for ($i = $registered + 1; $i <= $registered + $new; $i++) {
			if ($this->checker->check_chars($_POST["member_{$i}"], "lid #$i heeft een ongeldige gebruikersnaam")) {
				$sqlresult = db_do_query($page, db_query_select(array(array('user_id')), array('MEMBER'), "nick LIKE '{$_POST["member_{$i}"]}'"));
				$ok = $ok && $this->checker->check_input(db_num_rows($sqlresult) == 1, "lid '{$_POST["member_{$i}"]}' is onbekend");
			}
		}
		
		$registered = intval($_POST['registered_games']);
		$new = ($_POST['new_games'] != "NONE") ? intval($_POST['new_games']) : 0;
		for ($i = 1; $i <= $registered; $i++) {
			$ok = $ok && $this->checker->check_int($_POST["game_{$i}_freq"], "spel #$i");
			$ok = $ok && $this->checker->check_input($_POST["game_{$i}_freq"] > 0, "spel #$i - frequentie niet ingevuld");
		}
		for ($i = $registered+1; $i <= $registered + $new; $i++) {
			$ok = $ok && $this->checker->check_int($_POST["game_{$i}_freq"], "spel #$i");
			$ok = $ok && $this->checker->check_input($_POST["game_{$i}_freq"] > 0, "spel #$i - frequentie niet ingevuld");
			if ($_POST["game_{$i}"] == "NEW") {
				$ok = $ok && $this->checker->check_int($_POST["game_{$i}_type"], "spel #$i - soort");
				$ok = $ok && $this->checker->check_input($_POST["game_{$i}_type"], "spel #$i - soort niet ingevuld");
				$ok = $ok && $this->checker->check_exists($_POST["game_{$i}_name"], "spel #$i - naam");
				$ok = $ok && $this->checker->check_tags($_POST["game_{$i}_name"], "spel #$i - naam");
			} else {
				$ok = $ok && $this->checker->check_int($_POST["game_{$i}"], "spel #$i");
				$ok = $ok && $this->checker->check_input($_POST["game_{$i}"] > 0, "spel #$i niet ingevuld");
			}
		}
		return $ok;
	}
}

class GroupDefaultAction extends GroupAction implements iAction {
	public function execute() {
		$this->alerter->add_alert("unknown action: $action");
	}
}


class GroupAction {
	public static function getAction($action) {
		switch($action) {
			case "edit":
				$groupAction = new GroupEditAction();
				return $groupAction;
			case "add":
				$groupAction = new GroupAddAction();
				return $groupAction;
			default:
				$groupAction = new GroupDefaultAction();
				return $groupAction;
		}
	}
}
?>
